2023.4.20 修正
windowの基準、ラムダを手動で決定する
算出日を手動で決定し、その日のインデックスを算出できる
Al Barsha South Fourth
パーセンタイル 35-65
λ = 0.5
https://scrapbox.io/files/644444b445e5ee001bbd07cc.png
λ = 0.9
https://scrapbox.io/files/64444a4e6f751a001b845380.png
Marsa Dubai λ=0.9
https://scrapbox.io/files/6444511fb4af09001c519438.png
λ=0.3
https://scrapbox.io/files/644454fb6dde5e001c03ec5e.png
code:python
import pandas as pd
from datetime import timedelta
import statsmodels.api as sm
from sklearn.linear_model import LinearRegression
from sklearn.feature_selection import SelectKBest, f_regression
from sklearn.feature_selection import RFE
import numpy as np
import matplotlib.pyplot as plt
import datetime
pd.set_option('display.max_columns', None)
df_sale = pd.read_csv('Transactions.csv')
import warnings
warnings.filterwarnings('ignore')
df_sale = df_sale'instance_date', 'area_name_en', 'building_name_en', 'master_project_en', "meter_sale_price"
df_sale = df_sale.rename(columns={'instance_date': 'date'})
df_sale = df_sale.rename(columns={'area_name_en': 'area'})
df_sale = df_sale.rename(columns={'building_name_en': 'building'})
df_sale = df_sale.rename(columns={'master_project_en': 'project'})
# 日付列をdatetime型に変換
df_sale'date' = pd.to_datetime(df_sale'date', format='%d-%m-%Y') df_sale.set_index('date', inplace=True)
df_sale.index = pd.to_datetime(df_sale.index)
df_sale = df_sale.sort_index()
percentile_df_sale
end_date = datetime.datetime(2023,2,20)
# エリアごとの最初の取引日を計算
area_first_dates = df_sale.reset_index().groupby('area')'date'.min() # インデックスを算出したい日
calculation_date = end_date
# エリアごとの取引数をカウント
area_transactions_counts = df_sale.groupby('area')'area'.count() # エリアごとの取引数を格納するデータフレームを初期化
for area in area_transactions_counts.index:
# エリアごとの最初の取引日と算出したい日の差を計算
days_diff = (calculation_date - area_first_dates.locarea).days # エリアの取引数を取得
transactions_count = area_transactions_counts.locarea # 平均取引数を計算
mean_transactions = transactions_count / days_diff
# 結果をデータフレームに追加
df_area_tx_times = df_area_tx_times.append({'area': area,
'mean_transactions': mean_transactions},
ignore_index=True)
# エリアをインデックスに設定
df_area_tx_times = df_area_tx_times.set_index('area')
# 基準表をデータフレームとして作成
window_mapping = pd.DataFrame({
'window': 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 'transactions_per_day': 0.666, 0.827, 1, 1.185, 1.384, 1.6, 1.83, 2.08, 2.363, 2.66, 3, 3.368, 3.777, 4.235, 4.75, 5.333, 6, 6.769, 7.666, 8.727, 10, 11.555, 13.5, 16 })
# df_area_tx_timesのmean_transactionsに基づいてウィンドウ期間を割り当てる関数
def assign_window(mean_transactions, window_mapping):
if mean_transactions <= 0.666:
return 30
elif mean_transactions >= 16:
return 7
else:
# 新しいカラムにウィンドウ期間を割り当て
# window_periodカラムの値を四捨五入して整数に変換
select_area = 'Marsa Dubai'
df_spe_area = percentile_df_sale[percentile_df_sale'area' == select_area] specified_date = end_date
# 同じ日付のインデックスでグループ化し、meter_sale_priceの中央値を計算
# 中央値を新しいデータフレームに変換
area_df_median = area_df_median.to_frame()
# area_df_medianデータフレームのインデックスをリセット
area_df_median.reset_index(inplace=True)
area_df_median.set_index('date', inplace=True)
area_df_median.index = pd.to_datetime(area_df_median.index)
area_df_median = area_df_median.sort_index()
# 新しいデータフレームのインデックスにおいて、日付を連続するように補完し、空欄の行は直前のデータを参照する。
area_df_median = area_df_median.asfreq('D', method='ffill')
# カラム meter_sale_price を線形補完
# ローリングウィンドウを適用して smoothed_price を計算
# 整数に変換されたwindow_periodカラムの値を取得
# rolling関数に渡す
# 動的ウィンドウを使って移動中央値を算出完了
lambda_ = 0.9
# 重みを計算
W_si = 1 - W_ti
# 最新のタイムリーデータを取得
# end_dateの1日前を取得
end_date_minus_one = end_date - datetime.timedelta(days=1)
# end_date以前の最新のデータを取得
# 最終的なインデックスを算出
# 直近7日間でのrolling
rolling_window = 7
latest_date = area_df_median.index.max()
latest_row = area_df_median.loc[area_df_median.index == latest_date, 'property_index'] latest_row'date' = latest_date latest_row'area' = select_area latest_row = latest_row.set_index('date')
if 'new_df' not in locals():
new_df = latest_row
else:
# インデックスが日付であることを確認
assert isinstance(new_df.index, pd.DatetimeIndex)
# 重複したインデックスを削除
# インデックスを日付でソート
new_df.sort_index(inplace=True)
# 日付を連続したものに変換し、直前のデータで補完
new_df = new_df.asfreq('D', method='ffill')
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
# 表示する日付の範囲を指定
start_date = '2022-12-28'
end_date = '2023-02-20'
# グラフの大きさを設定
fig, ax = plt.subplots(figsize=(16, 8))
# データをプロット
# グラフのx軸の範囲を設定
ax.set_xlim(pd.to_datetime(start_date), pd.to_datetime(end_date))
# グラフのタイトルとラベルを設定
ax.set_title('Property_index')
ax.set_xlabel('Date')
ax.set_ylabel('Index')
# グラフを表示
plt.show()